package org.loong.crypto.core.params;

import java.security.Key;

import org.loong.crypto.core.Parameters;
import org.loong.crypto.core.algorithm.EncryptionMethod;

/**
 * The Cipher (Encryption) parameters to encryption.
 */
public class CipherParameters implements Parameters {

    /**
     * The key index.
     */
    private Integer keyIndex;

    /**
     * The key.
     */
    private Key key;

    /**
     * The key bytes.
     */
    private byte[] keyBytes;

    /**
     * The encryption Method.
     */
    private EncryptionMethod encryptionMethod;

    /**
     * The iv.
     */
    private byte[] iv;

    /**
     * no args constructor.
     */
    public CipherParameters() {}

    /**
     * builder constructor.
     *
     * @param builder builder
     */
    private CipherParameters(final Builder builder) {
        this.keyIndex = builder.keyIndex;
        this.key = builder.key;
        this.keyBytes = builder.keyBytes;
        this.encryptionMethod = builder.encryptionMethod;
        this.iv = builder.iv;
    }

    /**
     * class builder.
     *
     * @return builder
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Gets the value of keyIndex.
     *
     * @return the value of keyIndex
     */
    public Integer getKeyIndex() {
        return keyIndex;
    }

    /**
     * Sets the keyIndex.
     *
     * @param keyIndex the keyIndex to set
     */
    public void setKeyIndex(final Integer keyIndex) {
        this.keyIndex = keyIndex;
    }

    /**
     * Gets the value of key.
     *
     * @return the value of key
     */
    public Key getKey() {
        return key;
    }

    /**
     * Sets the key.
     *
     * @param key the key to set
     */
    public void setKey(final Key key) {
        this.key = key;
    }

    /**
     * Gets the value of keyBytes.
     *
     * @return the value of keyBytes
     */
    public byte[] getKeyBytes() {
        return keyBytes;
    }

    /**
     * Sets the keyBytes.
     *
     * @param keyBytes the keyBytes to set
     */
    public void setKeyBytes(final byte[] keyBytes) {
        this.keyBytes = keyBytes;
    }

    /**
     * Gets the value of encryptionMethod.
     *
     * @return the value of encryptionMethod
     */
    public EncryptionMethod getEncryptionMethod() {
        return encryptionMethod;
    }

    /**
     * Sets the encryptionMethod.
     *
     * @param encryptionMethod the encryptionMethod to set
     */
    public void setEncryptionMethod(EncryptionMethod encryptionMethod) {
        this.encryptionMethod = encryptionMethod;
    }

    /**
     * Gets the value of iv.
     *
     * @return the value of iv
     */
    public byte[] getIv() {
        return iv;
    }

    /**
     * Sets the iv.
     *
     * @param iv the iv to set
     */
    public void setIv(final byte[] iv) {
        this.iv = iv;
    }

    /**
     * class builder.
     */
    public static final class Builder {

        private Integer keyIndex;

        private Key key;

        private byte[] keyBytes;

        private EncryptionMethod encryptionMethod;

        private byte[] iv;

        /**
         * no args constructor.
         */
        private Builder() {}

        /**
         * build new Object.
         *
         * @return this
         */
        public CipherParameters build() {
            return new CipherParameters(this);
        }

        /**
         * build keyIndex.
         *
         * @param keyIndex keyIndex
         * @return this
         */
        public Builder keyIndex(final Integer keyIndex) {
            this.keyIndex = keyIndex;
            return this;
        }

        /**
         * build key.
         *
         * @param key key
         * @return this
         */
        public Builder key(final Key key) {
            this.key = key;
            return this;
        }

        /**
         * build keyBytes.
         *
         * @param keyBytes keyBytes
         * @return this
         */
        public Builder keyBytes(final byte[] keyBytes) {
            this.keyBytes = keyBytes;
            return this;
        }

        /**
         * build encryptionMethod.
         *
         * @param encryptionMethod encryptionMethod
         * @return this
         */
        public Builder encryptionMethod(final EncryptionMethod encryptionMethod) {
            this.encryptionMethod = encryptionMethod;
            return this;
        }

        /**
         * build iv.
         *
         * @param iv iv
         * @return this
         */
        public Builder iv(final byte[] iv) {
            this.iv = iv;
            return this;
        }
    }
}
